﻿/*************************************************************************
* 计算机名：AA-FA-05
* CLR 版本：4.0.30319.42000
* 命名空间: Unity
* 类    名：RelayCommand
* 当 前 域：HYRC
* 创 建 人：dailuyu
* 创建时间：2021/6/11 16:53:45
* 描    述：
*  V0.01 2021 初版
*
*  Copyright (c) 2021 aatsr Corporation. All rights reserved.
*  ┌──────────────────────────────────┐
*  │　此技术信息为本公司机密信息，未经本公司书面同意禁止向第三方披露．　│
*  └──────────────────────────────────┘
***************************************************************************/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Input;

namespace Unity
{
    /// <summary>
    /// 自定义不带参数的命令。
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region Private Fileds

        /// <summary>
        /// 执行方法。
        /// </summary>
        readonly Action _execute;

        /// <summary>
        /// 检测方法能否执行。
        /// </summary>
        readonly Func<bool> _canExecute;

        #endregion

        #region Event

        /// <summary>
        /// 
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add
            {

                if (_canExecute != null)
                    CommandManager.RequerySuggested += value;
            }
            remove
            {

                if (_canExecute != null)
                    CommandManager.RequerySuggested -= value;
            }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// 带1个参数的构造函数。
        /// </summary>
        /// <param name="execute">命令执行的方法。</param>
        public RelayCommand(Action execute)
            : this(execute, null)
        {

        }

        /// <summary>
        /// 构造函数，当2个参数的构造函数。
        /// </summary>
        /// <param name="execute">命令执行的方法。</param>
        /// <param name="canExecute">检测命令是否能执行。</param>
        public RelayCommand(Action execute, Func<bool> canExecute)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }

            _execute = execute;
            _canExecute = canExecute;
        }

        #endregion

        #region Public Methods
        /// <summary>
        /// 能否执行命令。
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        [DebuggerStepThrough]
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute();
        }

        /// <summary>
        /// 执行命令。
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            _execute();
        }

        #endregion
    }

    /// <summary>
    /// 自定义带一个参数的命令。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RelayCommand<T> : ICommand
    {
        #region Private Fileds

        /// <summary>
        /// 带一个参数的命令执行方法。
        /// </summary>
        readonly Action<T> _execute = null;

        /// <summary>
        /// 检测满足条件的命令方法能否执行。
        /// </summary>
        readonly Predicate<T> _canExecute = null;

        #endregion

        #region Event

        /// <summary>
        /// 
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add
            {
                if (_canExecute != null)
                    CommandManager.RequerySuggested += value;
            }
            remove
            {
                if (_canExecute != null)
                    CommandManager.RequerySuggested -= value;
            }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// 带一个参数的构造函数。
        /// </summary>
        /// <param name="execute">带一个参数的命令执行方法。</param>
        public RelayCommand(Action<T> execute)
            : this(execute, null)
        {

        }

        /// <summary>
        /// 构造函数。
        /// </summary>
        /// <param name="execute">带一个参数的命令执行方法。</param>
        /// <param name="canExecute">检测满足条件的命令是否能执行。</param>
        public RelayCommand(Action<T> execute, Predicate<T> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 能否执行命令。
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        [DebuggerStepThrough]
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute((T)parameter);
        }

        /// <summary>
        /// 执行命令。
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }

        #endregion
    }
}